package com.kylin.core.commodity.web.facade.impl;

import com.kylin.commodity.api.dto.req.NewCommentReqDTO;
import com.kylin.commodity.api.dto.req.QueryCommentReqDTO;
import com.kylin.commodity.api.dto.req.QueryCommodityReqDTO;
import com.kylin.commodity.api.dto.resp.CommentRespDTO;
import com.kylin.commodity.api.dto.resp.CommodityLiteRespDTO;
import com.kylin.commodity.api.dto.resp.CommodityRespDTO;
import com.kylin.commodity.api.web.facade.CommodityPlatformFacade;
import com.kylin.core.commodity.query.handler.CommodityTranslator;
import com.kylin.core.common.web.facade.AbstractFacade;
import com.kylin.core.marketing.query.handler.MarketingTranslator;
import com.kylin.domain.authority.command.CommentCommodityCommand;
import com.kylin.domain.authority.command.QueryCommentCommand;
import com.kylin.domain.authority.command.QueryCommodityCommand;
import com.kylin.domain.authority.command.RemoveCommentCommand;
import com.kylin.domain.commodity.provider.CommodityProvider;
import com.kylin.domain.commodity.vo.CommentVO;
import com.kylin.domain.commodity.vo.CommodityVO;
import com.kylin.domain.marketing.provider.MarketingProvider;
import com.kylin.domain.marketing.vo.MarketingCampaignVO;
import com.kylin.domain.user.vo.WechatUserInfoVO;
import com.kylin.shared.common.PageResults;
import com.kylin.shared.common.Pagination;
import com.kylin.shared.common.ResponseWrapper;
import com.kylin.shared.common.anno.ArgsValid;
import com.kylin.shared.common.consts.Constants;
import com.kylin.shared.enums.ApprovalState;
import com.kylin.shared.enums.MarketingType;
import com.kylin.shared.enums.ResultCodeEnum;
import com.kylin.shared.enums.YesNoEnum;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RestController;

import java.util.Objects;
import java.util.Optional;

/**
 * 秒结实现接口
 * @author Damon S.
 * @version v1.0.1
 * @date 2019年10月20日 16:07
 */
@Slf4j
@RestController
@RequiredArgsConstructor
@Api(tags = "商品开放接口")
public class CommodityPlatformFacadeImpl extends AbstractFacade implements CommodityPlatformFacade {

    private final CommodityProvider commodityProvider;
    private final CommodityTranslator commodityTranslator;
    private final MarketingTranslator marketingTranslator;
    private final MarketingProvider marketingProvider;


    @Override
    @ArgsValid
    @ApiOperation(value = "获取商品列表", notes = "分页返回商品(商品列表页使用，信息精简版)，每页默认10条")
    public ResponseWrapper<Pagination<CommodityLiteRespDTO>> listCommodities(QueryCommodityReqDTO queryCommodityReqDTO) {
        QueryCommodityCommand.QueryCommodityCommandBuilder builder = QueryCommodityCommand.builder()
                .removed(Optional.ofNullable(queryCommodityReqDTO.getRemoved()).orElse(YesNoEnum.N))
                .shelved(Optional.ofNullable(queryCommodityReqDTO.getShelved()).orElse(YesNoEnum.Y))
                .approvalState(Optional.ofNullable(queryCommodityReqDTO.getApprovalState()).orElse(ApprovalState.APPROVED))
                .marketingType(Optional.ofNullable(queryCommodityReqDTO.getMarketingType()).orElse(MarketingType.NA))
                .pageIndex(Optional.ofNullable(queryCommodityReqDTO.getIndex()).orElse(Constants.START_PAGE_INDEX))
                .pageSize(Optional.ofNullable(queryCommodityReqDTO.getLimit()).orElse(Constants.DEFAULT_PAGE_SIZE));

        PageResults commodities = commodityProvider.findCommodities(builder.build());
        return new ResponseWrapper<>(new Pagination<>(
                commodities.getIndex(),
                commodities.getLimit(),
                commodities.getTotal(),
                commodityTranslator.toCommodityLiteRespDTO(
                        commodities.castResults(CommodityVO.class)
                )
        ));
    }

    @Override
    @ArgsValid
    @ApiOperation(value = "获取商品详情", notes = "根据商品ID获取商品详情(完整版详情)")
    public ResponseWrapper<CommodityRespDTO> findCommodityById(Long commodityId) {
        // 查询正常的商品信息，未找到则返回错误信息
        CommodityVO commodity = commodityProvider.findCommodityByCommodityId(commodityId);
        if (CommodityVO.EMPTY.equals(commodity)) {
            return new ResponseWrapper<>(ResultCodeEnum.NOT_FOUND);
        }
        CommodityRespDTO commodityRespDTO = commodityTranslator.toCommodityRespDTO(commodity);

        // 获取评论数据
        PageResults comments = commodityProvider.findComments(
                QueryCommentCommand.builder()
                        .pageIndex(Constants.LONG_ONE)
                        .pageSize(Constants.LONG_ONE)
                        .commodityId(commodityId).build()
        );
        if (comments.getTotal() > Constants.LONG_ZERO) {
            commodityRespDTO.setCommentTotal(comments.getTotal());
            commodityRespDTO.setComment(
                    commodityTranslator.toCommentRespDTO(comments.castResults(CommentVO.class).get(0))
            );
        }
        // 判断商品是否在某项活动中，存在则获取商品在活动中的信息
        MarketingCampaignVO campaign = marketingProvider.findCampaignByCommodityId(commodityId);
        if (!MarketingCampaignVO.EMPTY.equals(campaign)) {
            commodityRespDTO.setCampaign(
                    marketingTranslator.toCampaignRespDTO(campaign)
            );
            // 用商品活动信息替换相应的商品信息
            commodityTranslator.loadMarketingCommodityVO(
                    commodityRespDTO,
                    commodityProvider.findMarketingCommodity(commodityId)
            );
        }
        return new ResponseWrapper<>(commodityRespDTO);
    }

    @Override
    @ApiOperation(value = "获取商品描述信息", notes = "根据商品ID获取商品描述详情")
    public ResponseWrapper<String> findCommodityDescById(Long commodityId) {
        return new ResponseWrapper<>(
                commodityProvider.findCommodityHtmlByCommodityId(commodityId)
        );
    }

    @Override
    @ApiOperation(value = "获取商品评论", notes = "根据商品ID获取商品的所有评论，每页默认10条")
    public ResponseWrapper<Pagination<CommentRespDTO>> findCommentsByCommodityId(
            Long commodityId, QueryCommentReqDTO queryCommentReqDTO) {
        PageResults comments = this.commodityProvider.findComments(
                QueryCommentCommand.builder()
                        .pageSize(queryCommentReqDTO.getLimit())
                        .pageIndex(queryCommentReqDTO.getIndex())
                        .commodityId(commodityId).build()
        );
        return new ResponseWrapper<>(new Pagination<>(
                queryCommentReqDTO.getIndex(),
                Optional.ofNullable(queryCommentReqDTO.getLimit()).orElse(Constants.DEFAULT_PAGE_SIZE),
                comments.getTotal(),
                commodityTranslator.toCommentRespDTO(comments.castResults(CommentVO.class)))
        );
    }

    @Override
    @ApiOperation(value = "新增一条评论", notes = "新增评论")
    public ResponseWrapper<Boolean> attachComment(Long commodityId, NewCommentReqDTO newCommentReqDTO) {
        if (!Objects.equals(commodityId, newCommentReqDTO.getCommodityId())) {
            return new ResponseWrapper<>(ResultCodeEnum.BAD_REQUEST);
        }
        WechatUserInfoVO userInfo = super.getWxUserInfo();
        if (WechatUserInfoVO.EMPTY.equals(userInfo)) {
            return new ResponseWrapper<>(ResultCodeEnum.USER_NOT_EXIST);
        }
        this.commodityProvider.addComment(CommentCommodityCommand.builder()
                .commentedBy(Long.parseLong(userInfo.getUserId()))
                .content(newCommentReqDTO.getContent())
                .commodityId(commodityId).build()
        );

        return new ResponseWrapper<>();
    }

    @Override
    @ApiOperation(value = "删除一条评论", notes = "删除评论")
    public ResponseWrapper<Boolean> detachComment(Long commodityId, Long commentId) {
        WechatUserInfoVO userInfo = super.getWxUserInfo();
        if (WechatUserInfoVO.EMPTY.equals(userInfo)) {
            return new ResponseWrapper<>(ResultCodeEnum.USER_NOT_EXIST);
        }
        this.commodityProvider.removeComment(RemoveCommentCommand.builder()
                .removedBy(Long.parseLong(userInfo.getUserId()))
                .commodityId(commodityId)
                .commentId(commentId).build()
        );
        return new ResponseWrapper<>();
    }
}
